package org.springblade.tms.module.billing.base;

import cn.hutool.core.collection.ListUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.logging.log4j.util.Strings;
import org.springblade.common.utils.EnumUtils;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.tms.global.enums.OrderTypeEnum;
import org.springblade.tms.global.enums.TorTypeEnum;
import org.springblade.tms.global.enums.UserTypeEnum;
import org.springblade.tms.global.exception.CommonException;
import org.springblade.tms.module.billing.dto.TMBillingDTO;
import org.springblade.tms.module.billing.entity.TMBilling;
import org.springblade.tms.module.billing.service.IBillingService;
import org.springblade.tms.module.billing.vo.TMBillingVO;
import org.springblade.tms.module.billing.wrapper.BillingWrapper;
import org.springblade.tms.module.billingitem.dto.TMBillingItemDTO;
import org.springblade.tms.module.billingitem.entity.TMBillingItem;
import org.springblade.tms.module.billingitem.service.IBillingItemService;
import org.springblade.tms.module.billingitem.vo.TMBillingItemVO;
import org.springblade.tms.module.billingitem.wrapper.BillingItemWrapper;
import org.springblade.tms.module.currencytype.entity.TMCurrencyType;
import org.springblade.tms.module.currencytype.service.ICurrencyTypeService;
import org.springblade.tms.module.demandorder.entity.TMDemandOrder;
import org.springblade.tms.module.demandorder.service.IDemandOrderService;
import org.springblade.tms.module.demandorderitem.entity.TMDemandOrderItem;
import org.springblade.tms.module.demandorderitem.service.IDemandOrderItemService;
import org.springblade.tms.module.sap.base.SapRequestService;
import org.springblade.tms.module.sap.dto.SapBillingDTO;
import org.springblade.tms.module.sap.dto.SapBillingItemDTO;
import org.springblade.tms.module.signedinfo.entity.TMSignedInfo;
import org.springblade.tms.module.signedinfo.service.ISignedInfoService;
import org.springblade.tms.module.statementorder.dto.SettlementSheetDTO;
import org.springblade.tms.module.statementorder.entity.TMStatementOrder;
import org.springblade.tms.module.statementorder.service.IStatementOrderService;
import org.springblade.tms.module.statementorder.vo.TMStatementExcelOrderVO;
import org.springblade.tms.module.statementorder.vo.TMStatementOrderVO;
import org.springblade.tms.module.statementorder.wrapper.StatementOrderWrapper;
import org.springblade.tms.module.transportorder.entity.TMTransportOrder;
import org.springblade.tms.module.transportorder.service.ITransportOrderService;
import org.springblade.tms.module.transportorderitem.entity.TMTransportOrderItem;
import org.springblade.tms.module.transportorderitem.service.ITransportOrderItemService;
import org.springblade.tms.module.userinfo.base.DriverManagementService;
import org.springblade.tms.module.userinfo.entity.TMUserInfo;
import org.springblade.tms.module.userinfo.service.IUserInfoService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @projectName: BladeX
 * @package: org.springblade.tms.module.billing.base
 * @className: SettlementService
 * @author: yr
 * @description: 结算单发票
 * @date: 2022/4/20 10:12
 */
@Service
public class SettlementService {
    @Resource
    private IBillingService billingService;
    @Resource
    private IBillingItemService billingItemService;
    @Resource
    private ICurrencyTypeService currencyTypeService;
    @Resource
    private DriverManagementService driverManagementService;
    @Resource
    private SapRequestService requestService;
    @Resource
    private IStatementOrderService statementOrderService;
    @Resource
    private IDemandOrderService demandOrderService;
    @Resource
    private ITransportOrderService transportOrderService;
    @Resource
    private IUserInfoService userInfoService;
    @Resource
    private ITransportOrderItemService transportOrderItemService;
    @Resource
    private IDemandOrderItemService demandOrderItemService;
    @Resource
    private ISignedInfoService signedInfoService;

    /**
     * @param tmBilling:
     * @param query:
     * @return R<IPage < TMBillingVO>>
     * @author yr
     * @description 结算单发票列表查询
     * @date 2022/4/20 10:18
     */
    public R<IPage<TMBillingVO>> list(TMBillingDTO tmBilling, Query query) {
        List<TMUserInfo> carrierList = userInfoService.lambdaQuery()
                .like(Strings.isNotBlank(tmBilling.getCarrierName()), TMUserInfo::getName, tmBilling.getCarrierName())
                .apply(Strings.isBlank(tmBilling.getCarrierName()), "1=2")
                .list();
        List<String> CarrierNos = carrierList.stream().map(TMUserInfo::getTmId).collect(Collectors.toList());
        TMUserInfo tmUserInfo = driverManagementService.getTmUserInfo();
        LambdaQueryWrapper<TMBilling> tmBillingLambdaQueryWrapper = Condition.getQueryWrapper(new TMBilling()).lambda()
                .like(Strings.isNotBlank(tmBilling.getNo()), TMBilling::getNo, tmBilling.getNo())
                .in(!CarrierNos.isEmpty(), TMBilling::getCarrierNo, CarrierNos)
                .isNotNull(tmBilling.getWhetherToPost() != null && tmBilling.getWhetherToPost(), TMBilling::getPayStatus)
                .isNull(tmBilling.getWhetherToPost() != null && !tmBilling.getWhetherToPost(), TMBilling::getPayStatus)
                .between(tmBilling.getPostingDateBegins() != null, TMBilling::getPostingDate, tmBilling.getPostingDateBegins(), tmBilling.getEndOfPostingDate())
//			.between(tmBilling.getStart() != null, TMBilling::getCreateTime, tmBilling.getStart(), tmBilling.getEnd())
                .apply(CarrierNos.isEmpty() && Strings.isNotBlank(tmBilling.getCarrierName()), "1=2")
                .orderByDesc(TMBilling::getCreateTime, TMBilling::getId);
        if (tmUserInfo != null && tmUserInfo.getUserType().equals(UserTypeEnum.CARRIER.getValue())) {
            tmBillingLambdaQueryWrapper = tmBillingLambdaQueryWrapper.eq(TMBilling::getCarrierNo, tmUserInfo.getTmId());
        }
        IPage<TMBilling> page = billingService.page(Condition.getPage(query), tmBillingLambdaQueryWrapper);
        //封装承运商名称
        List<String> collect = page.getRecords().stream().map(TMBilling::getCarrierNo).collect(Collectors.toList());
        List<TMUserInfo> carriers = userInfoService.lambdaQuery()
                .in(!collect.isEmpty(), TMUserInfo::getTmId, collect)
                .apply(collect.isEmpty(), "1=2")
                .list();
        Map<String, String> carrierMapByTmId = carriers.stream().collect(Collectors.toMap(TMUserInfo::getTmId, TMUserInfo::getName));
        IPage<TMBillingVO> billingVOIPage = BillingWrapper.build().pageVO(page);
        billingVOIPage.getRecords().forEach(billing -> {
            billing.setCarrierName(carrierMapByTmId.get(billing.getCarrierNo()));
            if (Strings.isBlank(billing.getPayStatus())) {
                billing.setPayStatus("未过账");
            } else {
                billing.setPayStatus("已过账");
            }
        });
        return R.data(billingVOIPage);
    }

    /**
     * @param no:
     * @param query:
     * @return R<IPage < TMBillingItemVO>>
     * @author yr
     * @description 发票列表查询
     * @date 2022/4/20 10:38
     */
    public R<IPage<TMBillingItemVO>> detail(String no, Query query) {
        IPage<TMBillingItem> page = billingItemService.page(Condition.getPage(query), Condition.getQueryWrapper(new TMBillingItem()).lambda()
                .eq(TMBillingItem::getBillingId, no).orderByDesc(TMBillingItem::getCreateTime, TMBillingItem::getId));
        Map<String, Long> collect = currencyTypeService.lambdaQuery().list().stream().collect(Collectors.toMap(TMCurrencyType::getName, TMCurrencyType::getId));
        IPage<TMBillingItemVO> iPage = BillingItemWrapper.build().pageVO(page);
        iPage.getRecords().forEach(tmBillingItemVO -> tmBillingItemVO.setCurrencyId(collect.get(tmBillingItemVO.getCurrencyType())));
        return R.data(iPage);
    }

    /**
     * @param billingItemDTO:
     * @return Object
     * @author yr
     * @description 新增或修改发票
     * @date 2022/4/20 13:43
     */
    public Boolean saveOrUpdate(TMBillingItemDTO billingItemDTO) {
        int compare = billingItemDTO.getTax().add(billingItemDTO.getPrice()).compareTo(billingItemDTO.getTotal());
        if (compare != 0) {
            CommonException.throwCommonException("发票金额+发票税额必须等于价税合计");
        }
        List<TMBillingItem> tmBillingItems = billingItemService.lambdaQuery()
                .eq(TMBillingItem::getNo, billingItemDTO.getNo())
                .ne(billingItemDTO.getId() != null, TMBillingItem::getId, billingItemDTO.getId())
                .list();
        if (!tmBillingItems.isEmpty()) {
            CommonException.throwCommonException("发票号已存在");
        }
        TMBilling tmBilling = billingService.lambdaQuery().eq(TMBilling::getNo, billingItemDTO.getBillingId()).one();
        TMCurrencyType tmCurrencyType = currencyTypeService.lambdaQuery().eq(TMCurrencyType::getName, tmBilling.getDocCurrency()).one();
        if (billingItemDTO.getDoesItIncludeTax()) {
            billingItemDTO.setZsl(tmCurrencyType.getTaxRate());
        } else {
            billingItemDTO.setZsl(BigDecimal.valueOf(0));
        }
//        BigDecimal divide = billingItemDTO.getTotal().divide(BigDecimal.valueOf(1)
//                .add(billingItemDTO.getZsl().divide(BigDecimal.valueOf(100))), 2, BigDecimal.ROUND_HALF_UP);
//        billingItemDTO.setTax(divide.multiply(billingItemDTO.getZsl().divide(BigDecimal.valueOf(100))).setScale(2, BigDecimal.ROUND_HALF_UP));
//        billingItemDTO.setPrice(billingItemDTO.getTotal().subtract(billingItemDTO.getTax()));
        billingItemDTO.setCurrencyType(tmCurrencyType.getName());
        return billingItemService.saveOrUpdate(billingItemDTO);
    }

    /**
     * @param no:
     * @return Boolean
     * @author yr
     * @description 提交发票
     * @date 2022/4/25 9:59
     */
    public Boolean refer(String no) {
        ArrayList<String> nos = ListUtil.toList(no.split(","));
        List<TMBilling> billing = billingService.lambdaQuery().in(TMBilling::getNo, nos).list();
        List<TMBillingItem> billingItems = billingItemService.lambdaQuery().in(TMBillingItem::getBillingId, nos).list();
        BigDecimal price1 = billing.stream().map(TMBilling::getPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal price2 = billingItems.stream().map(TMBillingItem::getTotal).reduce(BigDecimal.ZERO, BigDecimal::add);
        int compareTo = price1.compareTo(price2);
        if (compareTo != 0) {
            throw CommonException.throwCommonException("税价合计必须等于结算单运费");
        }
        billing.forEach(tmBilling -> tmBilling.setSubmit(1));
        //上报sap
        Map<String, List<TMBilling>> billMap = billing.stream().collect(Collectors.groupingBy(TMBilling::getNo));
        List<TMStatementOrder> tmStatementOrderList = statementOrderService.lambdaQuery().in(TMStatementOrder::getNo, nos).list();
        Map<String, List<TMStatementOrder>> orderTypeMap = tmStatementOrderList.stream().collect(Collectors.groupingBy(TMStatementOrder::getOrderType));
        //拿到当前结算单对应的需求单
        List<TMStatementOrder> statementOrderList1 = orderTypeMap.get(OrderTypeEnum.DEMAND_LIST.value());
        if (statementOrderList1 == null) {
            statementOrderList1 = new ArrayList<>();
        }
        List<Long> demandListIds = statementOrderList1.stream().map(TMStatementOrder::getParentId).collect(Collectors.toList());
        Map<Long, String> demandOrderMap = demandOrderService.lambdaQuery()
                .in(!demandListIds.isEmpty(), TMDemandOrder::getId, demandListIds)
                .apply(demandListIds.isEmpty(), "1=2")
                .list()
                .stream().collect(Collectors.toMap(TMDemandOrder::getId, TMDemandOrder::getOrderNo));
        //拿到当前结算单对应的运输单
        List<TMStatementOrder> statementOrderList2 = orderTypeMap.get(OrderTypeEnum.SINGLE_TRANSPORT.value());
        if (statementOrderList2 == null) {
            statementOrderList2 = new ArrayList<>();
        }
        List<Long> singleTransportIds = statementOrderList2.stream().map(TMStatementOrder::getParentId).collect(Collectors.toList());
        Map<Long, String> transportOrderMap = transportOrderService.lambdaQuery()
                .in(!singleTransportIds.isEmpty(), TMTransportOrder::getId, singleTransportIds)
                .apply(singleTransportIds.isEmpty(), "1=2")
                .list()
                .stream().collect(Collectors.toMap(TMTransportOrder::getId, TMTransportOrder::getOrderNoNew));
        //根据结算单号分组
        Map<String, List<TMStatementOrder>> collect = tmStatementOrderList.stream().collect(Collectors.groupingBy(TMStatementOrder::getNo));
        //封装上报数据
        Map<String, List<TMBillingItem>> billingItemsMap = billingItems.stream().collect(Collectors.groupingBy(TMBillingItem::getBillingId));
        nos.forEach(s -> {
            if (billingItemsMap.get(s) == null) {
                CommonException.throwCommonException("发票不能为空");
            }
        });
        List<SapBillingDTO> sapBillingDTOList = new ArrayList<>();
        billingItemsMap.keySet().forEach(s -> {
            List<SapBillingDTO> sapBillingDTOS = BeanUtil.copy(billingItemsMap.get(s), SapBillingDTO.class);
            sapBillingDTOS.forEach(sapBillingDTO -> {
                sapBillingDTO.setBillingId(s);
                sapBillingDTO.setCarrierNo(billMap.get(s).get(0).getCarrierNo());
                sapBillingDTO.setFsdPur(billMap.get(s).get(0).getFsdPur());
                List<SapBillingItemDTO> billingItemList = new ArrayList<>();
                List<TMStatementOrder> statementOrderList = collect.get(s);
                if (statementOrderList != null) {
                    statementOrderList.forEach(tmStatementOrder -> {
                        SapBillingItemDTO sapBillingItemDTO = new SapBillingItemDTO();
                        sapBillingItemDTO.setItemId(tmStatementOrder.getItemId());
                        if (tmStatementOrder.getOrderType().equals(OrderTypeEnum.SINGLE_TRANSPORT.value())) {
                            sapBillingItemDTO.setTorId(transportOrderMap.get(tmStatementOrder.getParentId()));
                        } else {
                            sapBillingItemDTO.setTorId(demandOrderMap.get(tmStatementOrder.getParentId()));
                        }
                        SapBillingItemDTO sapBillingItem = BeanUtil.copy(sapBillingItemDTO, SapBillingItemDTO.class);
                        billingItemList.add(sapBillingItem);
                    });
                }
                sapBillingDTO.setItem(billingItemList);
            });
            sapBillingDTOList.addAll(sapBillingDTOS);
        });
        requestService.submitAnInvoice(sapBillingDTOList);
        return billingService.updateBatchById(billing);
    }

    /**
     * @param id:
     * @return R
     * @author yr
     * @description 删除结算单
     * @date 2022/9/6 15:25
     */
    public R deleteStatement(Long id) {
        TMBilling billing = billingService.getById(id);
        List<TMBillingItem> tmBillingItems = billingItemService.lambdaQuery().eq(TMBillingItem::getBillingId, billing.getNo()).list();
        if (!tmBillingItems.isEmpty()) {
            billingItemService.deleteLogic(tmBillingItems.stream().map(TMBillingItem::getId).collect(Collectors.toList()));
        }
        List<TMStatementOrder> statementOrderList = statementOrderService.lambdaQuery().eq(TMStatementOrder::getNo, billing.getNo()).list();
        if (statementOrderList == null) {
            CommonException.throwCommonException("运输结算单不存在");
        }
        statementOrderList.forEach(tmStatementOrder -> {
            tmStatementOrder.setNo("");
            tmStatementOrder.setStaging(false);
        });
        statementOrderService.updateBatchById(statementOrderList);
        return R.data(billingService.removeById(billing));
    }

    /**
     * @param settlementSheetDTO:
     * @return R
     * @author yr
     * @description 运输结算单明细
     * @date 2022/10/31
     */
    public R<IPage<TMStatementOrderVO>> statementInvoiceDetails(SettlementSheetDTO settlementSheetDTO, Query query) {
        if (settlementSheetDTO == null) {
            settlementSheetDTO = new SettlementSheetDTO();
        }
        //根据条件查出需求单和运输单
        List<TMDemandOrder> tmDemandOrders = demandOrderService.lambdaQuery()
                .like(Strings.isNotBlank(settlementSheetDTO.getFreightOrderType()), TMDemandOrder::getOrderType, settlementSheetDTO.getFreightOrderType())
                .like(Strings.isNotBlank(settlementSheetDTO.getCarrierName()), TMDemandOrder::getCarrierName, settlementSheetDTO.getCarrierName())
                .like(Strings.isNotBlank(settlementSheetDTO.getFreightOrder()), TMDemandOrder::getOrderNo, settlementSheetDTO.getFreightOrder())
                .like(Strings.isNotBlank(settlementSheetDTO.getDeliveryNote()), TMDemandOrder::getDeliverNo, settlementSheetDTO.getDeliveryNote()).list();
        List<TMTransportOrder> tmTransportOrders = transportOrderService.lambdaQuery()
                .like(Strings.isNotBlank(settlementSheetDTO.getFreightOrderType()), TMTransportOrder::getOrderType, settlementSheetDTO.getFreightOrderType())
                .like(Strings.isNotBlank(settlementSheetDTO.getCarrierName()), TMTransportOrder::getCarrierName, settlementSheetDTO.getCarrierName())
                .like(Strings.isNotBlank(settlementSheetDTO.getDeliveryNote()), TMTransportOrder::getDeliverNo, settlementSheetDTO.getDeliveryNote())
                .like(Strings.isNotBlank(settlementSheetDTO.getFreightOrder()), TMTransportOrder::getOrderNo, settlementSheetDTO.getFreightOrder())
                .like(Strings.isNotBlank(settlementSheetDTO.getShippingNoteNumber()), TMTransportOrder::getTransportNo, settlementSheetDTO.getShippingNoteNumber()).list();
        //获取运单和需求单id
        List<Long> demandOrderIds = tmDemandOrders.stream().map(TMDemandOrder::getId).collect(Collectors.toList());
        List<Long> transportOrderIds = tmTransportOrders.stream().map(TMTransportOrder::getId).collect(Collectors.toList());
        //根据需求单和运单查询出结算单
        TMUserInfo tmUserInfo = driverManagementService.getTmUserInfo();
        LambdaQueryWrapper<TMStatementOrder> tmStatementOrderLambdaQueryWrapper = Condition.getQueryWrapper(new TMStatementOrder()).lambda()
                .eq(TMStatementOrder::getNo, settlementSheetDTO.getNo())
                .and(LambdaQueryWrapper -> LambdaQueryWrapper.in(!transportOrderIds.isEmpty(), TMStatementOrder::getParentId, transportOrderIds).or()
                        .in(!demandOrderIds.isEmpty(), TMStatementOrder::getParentId, demandOrderIds)
                        .apply(demandOrderIds.isEmpty() && transportOrderIds.isEmpty(), "1=2"))
//			.groupBy(TMStatementOrder::getParentId)
                .orderByDesc(TMStatementOrder::getCreateTime, TMStatementOrder::getId);
        if (tmUserInfo != null && tmUserInfo.getUserType().equals(UserTypeEnum.CARRIER.getValue())) {
            tmStatementOrderLambdaQueryWrapper = tmStatementOrderLambdaQueryWrapper.eq(TMStatementOrder::getCarrierNo, tmUserInfo.getTmId());
        }
        IPage<TMStatementOrder> statementOrderIPage = statementOrderService.page(Condition.getPage(query), tmStatementOrderLambdaQueryWrapper);
        IPage<TMStatementOrderVO> tmStatementOrderVOIPage = StatementOrderWrapper.build().pageVO(statementOrderIPage);
        List<TMStatementOrderVO> statementOrderVOS = tmStatementOrderVOIPage.getRecords();
        //根据需求单和运输单id查询出物料信息
        List<TMTransportOrderItem> tmTransportOrderItems = transportOrderItemService.lambdaQuery()
                .in(!transportOrderIds.isEmpty(), TMTransportOrderItem::getParentId, transportOrderIds).list();
        List<TMDemandOrderItem> tmDemandOrderItems = demandOrderItemService.lambdaQuery()
                .in(!demandOrderIds.isEmpty(), TMDemandOrderItem::getParentId, demandOrderIds).list();
        Map<Long, List<TMDemandOrderItem>> demandOrderItemMap = tmDemandOrderItems.stream().collect(Collectors.groupingBy(TMDemandOrderItem::getParentId));
        Map<Long, List<TMTransportOrderItem>> transportItemMap = tmTransportOrderItems.stream().collect(Collectors.groupingBy(TMTransportOrderItem::getParentId));

        Map<Long, List<TMDemandOrder>> DemandOrderMap = tmDemandOrders.stream().collect(Collectors.groupingBy(TMDemandOrder::getId));
        Map<Long, List<TMTransportOrder>> transportOrderMap = tmTransportOrders.stream().collect(Collectors.groupingBy(TMTransportOrder::getId));
        //结算单vo数据封装
        List<TMSignedInfo> tmSignedInfos = signedInfoService.lambdaQuery().in(!transportOrderIds.isEmpty(), TMSignedInfo::getParentId, transportOrderIds).list();
        Map<Long, List<TMSignedInfo>> signedInfoMapByPrentId = tmSignedInfos.stream().collect(Collectors.groupingBy(TMSignedInfo::getParentId));
        for (TMStatementOrderVO statementOrderVO : statementOrderVOS) {
            if (statementOrderVO.getOrderType().equals(OrderTypeEnum.SINGLE_TRANSPORT.value())) {
                TMTransportOrder tmTransportOrder = transportOrderMap.get(statementOrderVO.getParentId()).get(0);
                statementOrderVO.setShippingNoteNumber(tmTransportOrder.getTransportNo());
                statementOrderVO.setDemandOrderNumber(DemandOrderMap.get(tmTransportOrder.getDemandId()).get(0).getDemandOrderNumber());
                statementOrderVO.setWerks(DemandOrderMap.get(tmTransportOrder.getDemandId()).get(0).getWerks());
                statementOrderVO.setFreightOrder(tmTransportOrder.getOrderNo());
                statementOrderVO.setFreightOrderType(tmTransportOrder.getOrderType());
                statementOrderVO.setDeliverNo(tmTransportOrder.getDeliverNo());
                statementOrderVO.setCarrierName(tmTransportOrder.getCarrierName());
                statementOrderVO.setLicensePlateNumber(tmTransportOrder.getCarNo());
                statementOrderVO.setDriver(tmTransportOrder.getDriverName());
                statementOrderVO.setContractCompany(tmTransportOrder.getContractCompany());
                statementOrderVO.setBillOfLadingNumber(tmTransportOrder.getBillOfLadingNumber());
                statementOrderVO.setCustomerName(tmTransportOrder.getCustomerName());
                statementOrderVO.setStartLocationName(tmTransportOrder.getStartLocationName());
                List<TMSignedInfo> signedInfos = signedInfoMapByPrentId.get(tmTransportOrder.getId());
                if (signedInfos != null) {
                    TMSignedInfo tmSignedInfo = signedInfos.get(0);
                    assert tmSignedInfo != null;
                    statementOrderVO.setNum(tmSignedInfo.getNum());
                }
                //封装源位置和物料
                statementOrderVO.setSourceLocationStreet(new StringBuilder(tmTransportOrder.getStartLocationArea())
                        .append(tmTransportOrder.getStartLocationCity()).append(tmTransportOrder.getStartLocationStreet()).toString());
                statementOrderVO.setDestinationStreet(new StringBuilder(tmTransportOrder.getTargetLocationArea())
                        .append(tmTransportOrder.getTargetLocationCity()).append(tmTransportOrder.getTargetLocationStreet()).toString());
                transportItemMap.get(tmTransportOrder.getId()).forEach(item -> {
                    statementOrderVO.setMaterialInformation(new StringBuilder(statementOrderVO.getMaterialInformation()).append(item.getMatDesc())
                            .append("*").append(item.getNum().toString()).append("(")
                            .append(item.getUnit()).append(")").toString());
                });
            } else {
                TMDemandOrder tmDemandOrder = DemandOrderMap.get(statementOrderVO.getParentId()).get(0);
                statementOrderVO.setDemandOrderNumber(tmDemandOrder.getDemandOrderNumber());
                statementOrderVO.setFreightOrder(tmDemandOrder.getOrderNo());
                statementOrderVO.setWerks(tmDemandOrder.getWerks());
                statementOrderVO.setFreightOrderType(tmDemandOrder.getOrderType());
                statementOrderVO.setDeliverNo(tmDemandOrder.getDeliverNo());
                statementOrderVO.setCarrierName(tmDemandOrder.getCarrierName());
                statementOrderVO.setContractCompany(tmDemandOrder.getContractCompany());
                statementOrderVO.setBillOfLadingNumber(tmDemandOrder.getBillOfLadingNumber());
                statementOrderVO.setCustomerName(tmDemandOrder.getCustomerName());
                statementOrderVO.setStartLocationName(tmDemandOrder.getStartLocationName());
                //封装源位置和物料
                statementOrderVO.setSourceLocationStreet(new StringBuilder(tmDemandOrder.getStartLocationArea())
                        .append(tmDemandOrder.getStartLocationCity()).append(tmDemandOrder.getStartLocationStreet()).toString());
                statementOrderVO.setDestinationStreet(new StringBuilder(tmDemandOrder.getTargetLocationArea())
                        .append(tmDemandOrder.getTargetLocationCity()).append(tmDemandOrder.getTargetLocationStreet()).toString());
                demandOrderItemMap.get(tmDemandOrder.getId()).forEach(item -> {
                    statementOrderVO.setMaterialInformation(new StringBuilder(statementOrderVO.getMaterialInformation()).append(item.getMatDesc())
                            .append("*").append(item.getNum().toString()).append("(")
                            .append(item.getUnit()).append(")").toString());
                });
            }
            //货运订单号去0
            statementOrderVO.setFreightOrder(Long.toString(Long.parseLong(statementOrderVO.getFreightOrder())));
        }
        statementOrderVOS.forEach(tmStatementOrderVO -> tmStatementOrderVO.setOrderType(OrderTypeEnum.getDescriptionByValue(tmStatementOrderVO.getOrderType())));
        return R.data(tmStatementOrderVOIPage);
    }

    /**
     * @USER: YYJ
     * @DATE: 2022/12/21 11:52
     * @DESCRIPTION: 结算单发票导出
     */
    public List<TMStatementExcelOrderVO> download(SettlementSheetDTO settlementSheetDTO) {
        if (settlementSheetDTO == null) {
            settlementSheetDTO = new SettlementSheetDTO();
        }
        //根据条件查出需求单和运输单
        List<TMDemandOrder> tmDemandOrders = demandOrderService.lambdaQuery()
                .like(Strings.isNotBlank(settlementSheetDTO.getFreightOrderType()), TMDemandOrder::getOrderType, settlementSheetDTO.getFreightOrderType())
                .like(Strings.isNotBlank(settlementSheetDTO.getCarrierName()), TMDemandOrder::getCarrierName, settlementSheetDTO.getCarrierName())
                .like(Strings.isNotBlank(settlementSheetDTO.getFreightOrder()), TMDemandOrder::getOrderNo, settlementSheetDTO.getFreightOrder())
                .like(Strings.isNotBlank(settlementSheetDTO.getDeliveryNote()), TMDemandOrder::getDeliverNo, settlementSheetDTO.getDeliveryNote()).list();
        List<TMTransportOrder> tmTransportOrders = transportOrderService.lambdaQuery()
                .like(Strings.isNotBlank(settlementSheetDTO.getFreightOrderType()), TMTransportOrder::getOrderType, settlementSheetDTO.getFreightOrderType())
                .like(Strings.isNotBlank(settlementSheetDTO.getCarrierName()), TMTransportOrder::getCarrierName, settlementSheetDTO.getCarrierName())
                .like(Strings.isNotBlank(settlementSheetDTO.getDeliveryNote()), TMTransportOrder::getDeliverNo, settlementSheetDTO.getDeliveryNote())
                .like(Strings.isNotBlank(settlementSheetDTO.getFreightOrder()), TMTransportOrder::getOrderNo, settlementSheetDTO.getFreightOrder())
                .like(Strings.isNotBlank(settlementSheetDTO.getShippingNoteNumber()), TMTransportOrder::getTransportNo, settlementSheetDTO.getShippingNoteNumber()).list();
        //获取运单和需求单id
        List<Long> demandOrderIds = tmDemandOrders.stream().map(TMDemandOrder::getId).collect(Collectors.toList());
        List<Long> transportOrderIds = tmTransportOrders.stream().map(TMTransportOrder::getId).collect(Collectors.toList());
        //根据需求单和运单查询出结算单
        TMUserInfo tmUserInfo = driverManagementService.getTmUserInfo();
        LambdaQueryWrapper<TMStatementOrder> tmStatementOrderLambdaQueryWrapper = Condition.getQueryWrapper(new TMStatementOrder()).lambda()
                .eq(TMStatementOrder::getNo, settlementSheetDTO.getNo())
                .and(LambdaQueryWrapper -> LambdaQueryWrapper.in(!transportOrderIds.isEmpty(), TMStatementOrder::getParentId, transportOrderIds).or()
                        .in(!demandOrderIds.isEmpty(), TMStatementOrder::getParentId, demandOrderIds)
                        .apply(demandOrderIds.isEmpty() && transportOrderIds.isEmpty(), "1=2"))
//			.groupBy(TMStatementOrder::getParentId)
                .orderByDesc(TMStatementOrder::getCreateTime, TMStatementOrder::getId);
        if (tmUserInfo != null && tmUserInfo.getUserType().equals(UserTypeEnum.CARRIER.getValue())) {
            tmStatementOrderLambdaQueryWrapper = tmStatementOrderLambdaQueryWrapper.eq(TMStatementOrder::getCarrierNo, tmUserInfo.getTmId());
        }
        List<TMStatementOrder> statementOrderIPage = statementOrderService.list(tmStatementOrderLambdaQueryWrapper);
        List<TMStatementOrderVO> statementOrderVOS = BeanUtil.copy(statementOrderIPage, TMStatementOrderVO.class);
        //根据需求单和运输单id查询出物料信息
        List<TMTransportOrderItem> tmTransportOrderItems = transportOrderItemService.lambdaQuery()
                .in(!transportOrderIds.isEmpty(), TMTransportOrderItem::getParentId, transportOrderIds).list();
        List<TMDemandOrderItem> tmDemandOrderItems = demandOrderItemService.lambdaQuery()
                .in(!demandOrderIds.isEmpty(), TMDemandOrderItem::getParentId, demandOrderIds).list();
        Map<Long, List<TMDemandOrderItem>> demandOrderItemMap = tmDemandOrderItems.stream().collect(Collectors.groupingBy(TMDemandOrderItem::getParentId));
        Map<Long, List<TMTransportOrderItem>> transportItemMap = tmTransportOrderItems.stream().collect(Collectors.groupingBy(TMTransportOrderItem::getParentId));

        Map<Long, List<TMDemandOrder>> DemandOrderMap = tmDemandOrders.stream().collect(Collectors.groupingBy(TMDemandOrder::getId));
        Map<Long, List<TMTransportOrder>> transportOrderMap = tmTransportOrders.stream().collect(Collectors.groupingBy(TMTransportOrder::getId));
        //结算单vo数据封装
        List<TMSignedInfo> tmSignedInfos = signedInfoService.lambdaQuery().in(!transportOrderIds.isEmpty(), TMSignedInfo::getParentId, transportOrderIds).list();
        Map<Long, List<TMSignedInfo>> signedInfoMapByPrentId = tmSignedInfos.stream().collect(Collectors.groupingBy(TMSignedInfo::getParentId));
        for (TMStatementOrderVO statementOrderVO : statementOrderVOS) {
            if (statementOrderVO.getOrderType().equals(OrderTypeEnum.SINGLE_TRANSPORT.value())) {
                TMTransportOrder tmTransportOrder = transportOrderMap.get(statementOrderVO.getParentId()).get(0);
                statementOrderVO.setShippingNoteNumber(tmTransportOrder.getTransportNo());
                statementOrderVO.setDemandOrderNumber(DemandOrderMap.get(tmTransportOrder.getDemandId()).get(0).getDemandOrderNumber());
                statementOrderVO.setWerks(DemandOrderMap.get(tmTransportOrder.getDemandId()).get(0).getWerks());
                statementOrderVO.setFreightOrder(tmTransportOrder.getOrderNo());
                statementOrderVO.setFreightOrderType(tmTransportOrder.getOrderType());
                Optional<TorTypeEnum> enumByValue = EnumUtils.getEnumByValue(TorTypeEnum.class, tmTransportOrder.getOrderType());
                if (enumByValue != null) {
                    statementOrderVO.setFreightOrderType(enumByValue.get().description());
                }
                statementOrderVO.setDeliverNo(tmTransportOrder.getDeliverNo());
                statementOrderVO.setCarrierName(tmTransportOrder.getCarrierName());
                statementOrderVO.setLicensePlateNumber(tmTransportOrder.getCarNo());
                statementOrderVO.setDriver(tmTransportOrder.getDriverName());
                statementOrderVO.setContractCompany(tmTransportOrder.getContractCompany());
                statementOrderVO.setBillOfLadingNumber(tmTransportOrder.getBillOfLadingNumber());
                statementOrderVO.setCustomerName(tmTransportOrder.getCustomerName());
                statementOrderVO.setStartLocationName(tmTransportOrder.getStartLocationName());
                List<TMSignedInfo> signedInfos = signedInfoMapByPrentId.get(tmTransportOrder.getId());
                if (signedInfos != null) {
                    TMSignedInfo tmSignedInfo = signedInfos.get(0);
                    assert tmSignedInfo != null;
                    statementOrderVO.setNum(tmSignedInfo.getNum());
                }
                //封装源位置和物料
                statementOrderVO.setSourceLocationStreet(new StringBuilder(tmTransportOrder.getStartLocationArea())
                        .append(tmTransportOrder.getStartLocationCity()).append(tmTransportOrder.getStartLocationStreet()).toString());
                statementOrderVO.setDestinationStreet(new StringBuilder(tmTransportOrder.getTargetLocationArea())
                        .append(tmTransportOrder.getTargetLocationCity()).append(tmTransportOrder.getTargetLocationStreet()).toString());
                transportItemMap.get(tmTransportOrder.getId()).forEach(item -> {
                    statementOrderVO.setMaterialInformation(new StringBuilder(statementOrderVO.getMaterialInformation()).append(item.getMatDesc())
                            .append("*").append(item.getNum().toString()).append("(")
                            .append(item.getUnit()).append(")").toString());
                });
            } else {
                TMDemandOrder tmDemandOrder = DemandOrderMap.get(statementOrderVO.getParentId()).get(0);
                statementOrderVO.setDemandOrderNumber(tmDemandOrder.getDemandOrderNumber());
                statementOrderVO.setFreightOrder(tmDemandOrder.getOrderNo());
                statementOrderVO.setWerks(tmDemandOrder.getWerks());
                statementOrderVO.setFreightOrderType(tmDemandOrder.getOrderType());
                Optional<TorTypeEnum> enumByValue = EnumUtils.getEnumByValue(TorTypeEnum.class, tmDemandOrder.getOrderType());
                if (enumByValue != null) {
                    statementOrderVO.setFreightOrderType(enumByValue.get().description());
                }
                statementOrderVO.setDeliverNo(tmDemandOrder.getDeliverNo());
                statementOrderVO.setCarrierName(tmDemandOrder.getCarrierName());
                statementOrderVO.setContractCompany(tmDemandOrder.getContractCompany());
                statementOrderVO.setBillOfLadingNumber(tmDemandOrder.getBillOfLadingNumber());
                statementOrderVO.setCustomerName(tmDemandOrder.getCustomerName());
                statementOrderVO.setStartLocationName(tmDemandOrder.getStartLocationName());
                //封装源位置和物料
                statementOrderVO.setSourceLocationStreet(new StringBuilder(tmDemandOrder.getStartLocationArea())
                        .append(tmDemandOrder.getStartLocationCity()).append(tmDemandOrder.getStartLocationStreet()).toString());
                statementOrderVO.setDestinationStreet(new StringBuilder(tmDemandOrder.getTargetLocationArea())
                        .append(tmDemandOrder.getTargetLocationCity()).append(tmDemandOrder.getTargetLocationStreet()).toString());
                demandOrderItemMap.get(tmDemandOrder.getId()).forEach(item -> {
                    statementOrderVO.setMaterialInformation(new StringBuilder(statementOrderVO.getMaterialInformation()).append(item.getMatDesc())
                            .append("*").append(item.getNum().toString()).append("(")
                            .append(item.getUnit()).append(")").toString());
                });
            }
            //货运订单号去0
            statementOrderVO.setFreightOrder(Long.toString(Long.parseLong(statementOrderVO.getFreightOrder())));
        }
        statementOrderVOS.forEach(tmStatementOrderVO -> tmStatementOrderVO.setOrderType(OrderTypeEnum.getDescriptionByValue(tmStatementOrderVO.getOrderType())));
        return BeanUtil.copy(statementOrderVOS, TMStatementExcelOrderVO.class);
    }


}
